"""Template storage using JSON files.""" import uuid from datetime import datetime, timezone from typing import Dict, List, Optional from wled_controller.core.capture_engines.factory import EngineRegistry from wled_controller.storage.base_store import BaseJsonStore from wled_controller.storage.template import CaptureTemplate from wled_controller.utils import get_logger logger = get_logger(__name__) class TemplateStore(BaseJsonStore[CaptureTemplate]): """Storage for capture templates. All templates are persisted to the JSON file. On startup, if no templates exist, one is auto-created using the highest-priority available engine. """ _json_key = "templates" _entity_name = "Capture template" def __init__(self, file_path: str): super().__init__(file_path, CaptureTemplate.from_dict) self._ensure_initial_template() # Backward-compatible aliases get_all_templates = BaseJsonStore.get_all get_template = BaseJsonStore.get delete_template = BaseJsonStore.delete def _ensure_initial_template(self) -> None: """Auto-create a template if none exist, using the best available engine.""" if self._items: return best_engine = EngineRegistry.get_best_available_engine() if not best_engine: logger.warning("No capture engines available, cannot create initial template") return engine_class = EngineRegistry.get_engine(best_engine) default_config = engine_class.get_default_config() now = datetime.now(timezone.utc) template_id = f"tpl_{uuid.uuid4().hex[:8]}" template = CaptureTemplate( id=template_id, name="Default", engine_type=best_engine, engine_config=default_config, created_at=now, updated_at=now, description=f"Default capture template using {best_engine.upper()} engine", ) self._items[template_id] = template self._save() logger.info(f"Auto-created initial template: {template.name} ({template_id}, engine={best_engine})") def create_template( self, name: str, engine_type: str, engine_config: Dict[str, any], description: Optional[str] = None, tags: Optional[List[str]] = None, ) -> CaptureTemplate: self._check_name_unique(name) template_id = f"tpl_{uuid.uuid4().hex[:8]}" now = datetime.now(timezone.utc) template = CaptureTemplate( id=template_id, name=name, engine_type=engine_type, engine_config=engine_config, created_at=now, updated_at=now, description=description, tags=tags or [], ) self._items[template_id] = template self._save() logger.info(f"Created template: {name} ({template_id})") return template def update_template( self, template_id: str, name: Optional[str] = None, engine_type: Optional[str] = None, engine_config: Optional[Dict[str, any]] = None, description: Optional[str] = None, tags: Optional[List[str]] = None, ) -> CaptureTemplate: template = self.get(template_id) if name is not None: self._check_name_unique(name, exclude_id=template_id) template.name = name if engine_type is not None: template.engine_type = engine_type if engine_config is not None: template.engine_config = engine_config if description is not None: template.description = description if tags is not None: template.tags = tags template.updated_at = datetime.now(timezone.utc) self._save() logger.info(f"Updated template: {template_id}") return template