j
This commit is contained in:
@@ -205,36 +205,71 @@ class SharedArgs:
|
||||
def get_store_choices(config: Optional[Dict[str, Any]] = None) -> List[str]:
|
||||
"""Get list of available store backend names.
|
||||
|
||||
This method dynamically discovers all configured storage backends
|
||||
instead of using a static list. Should be called when building
|
||||
autocomplete choices or validating store names.
|
||||
This method returns the cached list of available backends from the most
|
||||
recent startup check. Stores that failed to initialize are filtered out.
|
||||
Users must restart to refresh the list if stores are enabled/disabled.
|
||||
|
||||
Args:
|
||||
config: Optional config dict. If not provided, will try to load from config module.
|
||||
config: Ignored (kept for compatibility); uses cached startup result.
|
||||
|
||||
Returns:
|
||||
List of backend names (e.g., ['default', 'test', 'home', 'work'])
|
||||
Only includes backends that successfully initialized at startup.
|
||||
|
||||
Example:
|
||||
SharedArgs.STORE.choices = SharedArgs.get_store_choices(config)
|
||||
"""
|
||||
# Use the cached startup check result if available
|
||||
if hasattr(SharedArgs, "_cached_available_stores"):
|
||||
return SharedArgs._cached_available_stores or []
|
||||
|
||||
# Fallback to configured names if cache doesn't exist yet
|
||||
# (This shouldn't happen in normal operation, but provides a safe fallback)
|
||||
try:
|
||||
# Use the non-instantiating helper so autocomplete doesn't trigger backend init.
|
||||
from Store.registry import list_configured_backend_names
|
||||
|
||||
# If no config provided, try to load it
|
||||
if config is None:
|
||||
try:
|
||||
from SYS.config import load_config
|
||||
config = load_config()
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
return list_configured_backend_names(config)
|
||||
return list_configured_backend_names(config) or []
|
||||
except Exception:
|
||||
# Fallback to empty list if FileStorage isn't available
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
def _refresh_store_choices_cache(config: Optional[Dict[str, Any]] = None) -> None:
|
||||
"""Refresh the cached store choices list. Should be called once at startup.
|
||||
|
||||
This performs the actual StoreRegistry initialization check and caches the result.
|
||||
Subsequent calls to get_store_choices() will use this cache.
|
||||
|
||||
Args:
|
||||
config: Config dict. If not provided, will try to load from config module.
|
||||
"""
|
||||
try:
|
||||
if config is None:
|
||||
try:
|
||||
from SYS.config import load_config
|
||||
config = load_config()
|
||||
except Exception:
|
||||
SharedArgs._cached_available_stores = []
|
||||
return
|
||||
|
||||
# Initialize registry once to filter disabled stores
|
||||
from Store.registry import Store as StoreRegistry
|
||||
|
||||
try:
|
||||
registry = StoreRegistry(config=config, suppress_debug=True)
|
||||
available = registry.list_backends()
|
||||
SharedArgs._cached_available_stores = available or []
|
||||
except Exception:
|
||||
# If registry creation fails, fallback to configured names
|
||||
from Store.registry import list_configured_backend_names
|
||||
SharedArgs._cached_available_stores = list_configured_backend_names(config) or []
|
||||
except Exception:
|
||||
SharedArgs._cached_available_stores = []
|
||||
|
||||
LOCATION = CmdletArg(
|
||||
"location",
|
||||
type="enum",
|
||||
|
||||
@@ -321,12 +321,10 @@ class Add_File(Cmdlet):
|
||||
is_storage_backend_location = False
|
||||
if location:
|
||||
try:
|
||||
# Use a config-only check to avoid instantiating backends (which may perform network checks).
|
||||
from Store.registry import list_configured_backend_names
|
||||
|
||||
is_storage_backend_location = location in (
|
||||
list_configured_backend_names(config) or []
|
||||
)
|
||||
# Check against the cached startup list of available backends
|
||||
from cmdlet._shared import SharedArgs
|
||||
available_backends = SharedArgs.get_store_choices(config)
|
||||
is_storage_backend_location = location in available_backends
|
||||
except Exception:
|
||||
is_storage_backend_location = False
|
||||
|
||||
@@ -546,7 +544,10 @@ class Add_File(Cmdlet):
|
||||
# Update pipe_obj with resolved path
|
||||
pipe_obj.path = str(media_path)
|
||||
|
||||
if not self._validate_source(media_path):
|
||||
# When using -path (filesystem export), allow all file types.
|
||||
# When using -store (backend), restrict to SUPPORTED_MEDIA_EXTENSIONS.
|
||||
allow_all_files = not (location and is_storage_backend_location)
|
||||
if not self._validate_source(media_path, allow_all_extensions=allow_all_files):
|
||||
failures += 1
|
||||
continue
|
||||
|
||||
@@ -1193,8 +1194,15 @@ class Add_File(Cmdlet):
|
||||
return files_info
|
||||
|
||||
@staticmethod
|
||||
def _validate_source(media_path: Optional[Path]) -> bool:
|
||||
"""Validate that the source file exists and is supported."""
|
||||
@staticmethod
|
||||
def _validate_source(media_path: Optional[Path], allow_all_extensions: bool = False) -> bool:
|
||||
"""Validate that the source file exists and is supported.
|
||||
|
||||
Args:
|
||||
media_path: Path to the file to validate
|
||||
allow_all_extensions: If True, skip file type filtering (used for -path exports).
|
||||
If False, only allow SUPPORTED_MEDIA_EXTENSIONS (used for -store).
|
||||
"""
|
||||
if media_path is None:
|
||||
return False
|
||||
|
||||
@@ -1214,11 +1222,12 @@ class Add_File(Cmdlet):
|
||||
log(f"File not found: {media_path}")
|
||||
return False
|
||||
|
||||
# Validate file type
|
||||
file_extension = media_path.suffix.lower()
|
||||
if file_extension not in SUPPORTED_MEDIA_EXTENSIONS:
|
||||
log(f"❌ Unsupported file type: {file_extension}", file=sys.stderr)
|
||||
return False
|
||||
# Validate file type: only when adding to -store backend, not for -path exports
|
||||
if not allow_all_extensions:
|
||||
file_extension = media_path.suffix.lower()
|
||||
if file_extension not in SUPPORTED_MEDIA_EXTENSIONS:
|
||||
log(f"❌ Unsupported file type: {file_extension}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
Reference in New Issue
Block a user