fix: use configured directory for image scan instead of always auto-detecting

_find_comfyui_output_dir() now checks GalleryConfig.MONITORING_DIRECTORIES
first before falling back to filesystem auto-detection. Also invalidates
the cached directory when the user changes the setting via save_settings().

Closes #108
This commit is contained in:
Vito Sansevero
2026-02-09 04:52:03 -08:00
parent 0a2c274a27
commit 6a5834e243
3 changed files with 145 additions and 2 deletions
+28 -2
View File
@@ -448,8 +448,15 @@ class PromptManagerAPI(
def _find_comfyui_output_dir(self):
"""Locate the ComfyUI output directory using multiple detection strategies.
Results are cached after first successful lookup since the output
directory does not change during runtime.
Checks in order:
1. User-configured directory (GalleryConfig.MONITORING_DIRECTORIES)
2. Upward filesystem search for ComfyUI markers
3. Common installation path patterns
4. Common ComfyUI installation locations
Results are cached after first successful lookup. The cache is
invalidated when the user changes the configured directory via
save_settings().
Returns:
str or None: Absolute path to ComfyUI output directory, or None
@@ -458,6 +465,25 @@ class PromptManagerAPI(
if self._cached_output_dir is not None:
return self._cached_output_dir
# Method 0: Check user-configured directory first
try:
from ..config import GalleryConfig
if GalleryConfig.MONITORING_DIRECTORIES:
configured_dir = Path(GalleryConfig.MONITORING_DIRECTORIES[0]).resolve()
if configured_dir.exists() and configured_dir.is_dir():
self.logger.info(
f"Using configured monitoring directory: {configured_dir}"
)
self._cached_output_dir = str(configured_dir)
return self._cached_output_dir
else:
self.logger.warning(
f"Configured directory does not exist: {GalleryConfig.MONITORING_DIRECTORIES[0]}"
)
except ImportError:
pass
current_file = Path(__file__).resolve()
self.logger.debug(f"Starting ComfyUI output search from: {current_file}")
+2
View File
@@ -448,6 +448,8 @@ class AdminRoutesMixin:
GalleryConfig.MONITORING_DIRECTORIES = [new_path]
else:
GalleryConfig.MONITORING_DIRECTORIES = []
# Invalidate cached output dir so next lookup uses new config
self._cached_output_dir = None
restart_required = True
# Save to config file for persistence
+115
View File
@@ -0,0 +1,115 @@
"""
Tests for _find_comfyui_output_dir() — verifies that user-configured
directories take priority over auto-detection, and that the cache is
invalidated when the setting changes.
"""
import os
import sys
import tempfile
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# Mock ComfyUI's server module before importing anything that touches config
_mock_server = MagicMock()
_mock_server.PromptServer.instance.routes = MagicMock()
sys.modules["server"] = _mock_server
from py.api import PromptManagerAPI
from py.config import GalleryConfig
class TestFindComfyuiOutputDir(unittest.TestCase):
"""Test _find_comfyui_output_dir() respects user-configured directories."""
def setUp(self):
self.api = PromptManagerAPI()
self.api._cached_output_dir = None
self._orig_dirs = list(GalleryConfig.MONITORING_DIRECTORIES)
def tearDown(self):
GalleryConfig.MONITORING_DIRECTORIES = self._orig_dirs
def test_configured_directory_takes_priority(self):
"""When a valid directory is configured, it should be used instead of auto-detect."""
with tempfile.TemporaryDirectory() as tmpdir:
GalleryConfig.MONITORING_DIRECTORIES = [tmpdir]
self.api._cached_output_dir = None
result = self.api._find_comfyui_output_dir()
self.assertEqual(result, str(Path(tmpdir).resolve()))
def test_nonexistent_configured_directory_falls_through(self):
"""When the configured directory doesn't exist, fall back to auto-detection."""
GalleryConfig.MONITORING_DIRECTORIES = ["/nonexistent/fake/path/output"]
self.api._cached_output_dir = None
# Should not return the nonexistent path — will either find
# ComfyUI output via auto-detect or return None
result = self.api._find_comfyui_output_dir()
self.assertNotEqual(result, "/nonexistent/fake/path/output")
def test_empty_config_uses_auto_detection(self):
"""When MONITORING_DIRECTORIES is empty, auto-detection should be used."""
GalleryConfig.MONITORING_DIRECTORIES = []
self.api._cached_output_dir = None
# Should not raise — auto-detection may or may not find a dir
result = self.api._find_comfyui_output_dir()
# Result is either a valid path or None
if result is not None:
self.assertTrue(Path(result).is_dir())
def test_cache_returns_same_value(self):
"""After first lookup, cached value should be returned."""
with tempfile.TemporaryDirectory() as tmpdir:
GalleryConfig.MONITORING_DIRECTORIES = [tmpdir]
self.api._cached_output_dir = None
result1 = self.api._find_comfyui_output_dir()
# Change config — should NOT affect result because of cache
GalleryConfig.MONITORING_DIRECTORIES = ["/some/other/path"]
result2 = self.api._find_comfyui_output_dir()
self.assertEqual(result1, result2)
def test_cache_invalidation_picks_up_new_directory(self):
"""After clearing the cache, _find_comfyui_output_dir should use new config."""
with tempfile.TemporaryDirectory() as tmpdir1:
with tempfile.TemporaryDirectory() as tmpdir2:
GalleryConfig.MONITORING_DIRECTORIES = [tmpdir1]
self.api._cached_output_dir = None
result1 = self.api._find_comfyui_output_dir()
self.assertEqual(result1, str(Path(tmpdir1).resolve()))
# Simulate what save_settings does: update config + invalidate cache
GalleryConfig.MONITORING_DIRECTORIES = [tmpdir2]
self.api._cached_output_dir = None
result2 = self.api._find_comfyui_output_dir()
self.assertEqual(result2, str(Path(tmpdir2).resolve()))
def test_configured_directory_is_resolved(self):
"""Configured paths with symlinks or .. should be resolved to absolute."""
with tempfile.TemporaryDirectory() as tmpdir:
# Use a relative-ish path with ..
parent = str(Path(tmpdir).parent)
basename = Path(tmpdir).name
dotdot_path = os.path.join(parent, ".", basename)
GalleryConfig.MONITORING_DIRECTORIES = [dotdot_path]
self.api._cached_output_dir = None
result = self.api._find_comfyui_output_dir()
self.assertEqual(result, str(Path(tmpdir).resolve()))
if __name__ == "__main__":
unittest.main()