100 lines
3.3 KiB
Python
100 lines
3.3 KiB
Python
"""Store registry.
|
|
|
|
Concrete store implementations live in the `Store/` package.
|
|
This module is the single source of truth for store discovery.
|
|
|
|
Config schema (canonical):
|
|
|
|
{
|
|
"store": {
|
|
"folder": {
|
|
"default": {"path": "C:/Media"},
|
|
"test": {"path": "C:/Temp"}
|
|
},
|
|
"hydrusnetwork": {
|
|
"home": {"Hydrus-Client-API-Access-Key": "...", "url": "http://..."}
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Any, Dict, Optional
|
|
|
|
from SYS.logger import debug
|
|
|
|
from Store._base import StoreBackend
|
|
from Store.Folder import Folder
|
|
from Store.HydrusNetwork import HydrusNetwork
|
|
|
|
|
|
class Store:
|
|
def __init__(self, config: Optional[Dict[str, Any]] = None, suppress_debug: bool = False) -> None:
|
|
self._config = config or {}
|
|
self._suppress_debug = suppress_debug
|
|
self._backends: Dict[str, StoreBackend] = {}
|
|
self._load_backends()
|
|
|
|
def _load_backends(self) -> None:
|
|
store_cfg = self._config.get("store")
|
|
if not isinstance(store_cfg, dict):
|
|
store_cfg = {}
|
|
|
|
folder_cfg = store_cfg.get("folder")
|
|
if isinstance(folder_cfg, dict):
|
|
for name, value in folder_cfg.items():
|
|
path_val: Optional[str]
|
|
if isinstance(value, dict):
|
|
path_val = value.get("path")
|
|
elif isinstance(value, (str, bytes)):
|
|
path_val = str(value)
|
|
else:
|
|
path_val = None
|
|
|
|
if not path_val:
|
|
continue
|
|
|
|
location = str(Path(str(path_val)).expanduser())
|
|
self._backends[str(name)] = Folder(location=location, name=str(name))
|
|
|
|
hydrus_cfg = store_cfg.get("hydrusnetwork")
|
|
if isinstance(hydrus_cfg, dict):
|
|
for instance_name, instance_config in hydrus_cfg.items():
|
|
if not isinstance(instance_config, dict):
|
|
continue
|
|
|
|
api_key = instance_config.get("Hydrus-Client-API-Access-Key")
|
|
url = instance_config.get("url")
|
|
if not api_key or not url:
|
|
continue
|
|
|
|
try:
|
|
self._backends[str(instance_name)] = HydrusNetwork(
|
|
instance_name=str(instance_name),
|
|
api_key=str(api_key),
|
|
url=str(url),
|
|
)
|
|
except Exception as exc:
|
|
if not self._suppress_debug:
|
|
debug(f"[Store] Failed to register Hydrus instance '{instance_name}': {exc}")
|
|
|
|
def list_backends(self) -> list[str]:
|
|
return sorted(self._backends.keys())
|
|
|
|
def list_searchable_backends(self) -> list[str]:
|
|
searchable: list[str] = []
|
|
for name, backend in self._backends.items():
|
|
if type(backend).search_store is not StoreBackend.search_store:
|
|
searchable.append(name)
|
|
return sorted(searchable)
|
|
|
|
def __getitem__(self, backend_name: str) -> StoreBackend:
|
|
if backend_name not in self._backends:
|
|
raise KeyError(f"Unknown store backend: {backend_name}. Available: {list(self._backends.keys())}")
|
|
return self._backends[backend_name]
|
|
|
|
def is_available(self, backend_name: str) -> bool:
|
|
return backend_name in self._backends
|